package cn.tedu.charging.order.service.impl;

import cn.tedu.charging.common.constant.AmqpDeclareConst;
import cn.tedu.charging.common.constant.MqttTopicConst;
import cn.tedu.charging.common.pojo.message.DelayCheckMessage;
import cn.tedu.charging.common.pojo.message.StartCheckMessage;
import cn.tedu.charging.common.pojo.param.OrderAddParam;
import cn.tedu.charging.common.protocol.JsonResult;
import cn.tedu.charging.common.utils.SnowflakeIdGenerator;
import cn.tedu.charging.order.cilent.DeviceClient;
import cn.tedu.charging.order.cilent.UserClient;
import cn.tedu.charging.order.producer.AmqpDelayProducer;
import cn.tedu.charging.order.producer.MqttProducer;
import cn.tedu.charging.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private DeviceClient deviceClient;
    @Autowired
    private UserClient UserClient;
    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;
    @Autowired
    private MqttProducer<StartCheckMessage> mqttProducer;
    @Autowired
    private AmqpDelayProducer<DelayCheckMessage> amqpDelayProducer;
    @Override
    public String createOrder(OrderAddParam param) {
        //1.检查设备
        checkGunAvailable(param.getGunId());
        //2.检查车主
        checkChargeUserAvailable(param.getUserId(), param.getGunId());
        //3.订单编号生成-雪花算法
        String billId=generateBillId();
        //4.和设备通信
        sendStartCharging(billId,param);
        //5。发送延迟消息
        sendDelayMessage(billId,param);
        //6。为兜底检查订单最终状态
        //7.修改枪状态

        return billId;
    }

    private void sendDelayMessage(String billId, OrderAddParam param) {
        //1.封装接口DelayCheckMessage  缺少vehicleId
        DelayCheckMessage delayCheckMessage = new DelayCheckMessage();
        BeanUtils.copyProperties(param,delayCheckMessage);
        delayCheckMessage.setOrderNo(billId);
        //2.自定义AmqpDelayProducer发送延迟 1分钟(为什么1分钟,不是2分钟3分钟)
        amqpDelayProducer.sendDelay(
                AmqpDeclareConst.DELAY_BILL_EX,"",delayCheckMessage,1000*60);
    }


    private void sendStartCharging(String billId, OrderAddParam param) {
        //1.准备完整消息对象
        StartCheckMessage message=new StartCheckMessage();
        message.setOrderNo(billId);
        message.setUserId(param.getUserId());
        message.setGunId(param.getGunId());
        //2.调用send封装 发送给设备 charging/device/check/pileId
        mqttProducer.send(
                MqttTopicConst.START_GUN_CHECK_PREFIX+param.getPileId(),message);
    }

    private String generateBillId(){
        return snowflakeIdGenerator.nextId()+"";
    }
    private void checkGunAvailable(Integer gunId){
        JsonResult<Boolean> result = deviceClient.checkGun(gunId);
        Boolean available = result.getData();
        if(!available){
            throw new RuntimeException("枪状态异常,不可充电");
        }
    }
    private void checkChargeUserAvailable(Integer userId, Integer gunId){
        JsonResult<Boolean> result = UserClient.checkCharge(userId, gunId);
        Boolean available = result.getData();
        if(!available){
            throw new RuntimeException("用户状态异常,不可充电");
        }
    }
}
